home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
libgutil
/
psimg.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
13KB
|
534 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* psimg -
* Convert image data into b/w or color PostScript.
*
* Paul Haeberli - 1989
*
*/
#include "image.h"
#include "math.h"
typedef struct printspec {
float screendensity;
float screenangle;
float xpixperinch;
float ypixperinch;
float scaletrim;
float maxxsize, maxysize;
int bitsper, linescreen;
} printspec;
static short cortab[256];
static int pos;
static int psfirsted;
static IMAGE *inimage;
static int binaryout = 0;
static bwgetimgrow();
static rgbgetimgrow();
static hypcurve();
static putpsascrow();
static putpsbinrow();
static makepstables();
static psputchar();
static intervleave3();
static intervleave4();
usebinaryps(b)
int b;
{
binaryout = b;
}
static bwgetimgrow(buf,y)
short *buf;
int y;
{
getbwrow(inimage,buf,inimage->ysize-1-y);
}
static rgbgetimgrow(buf,y,z)
short *buf;
int y, z;
{
getrow(inimage,buf,inimage->ysize-1-y,z%inimage->zsize);
}
frametobwps(outf,image)
FILE *outf;
IMAGE *image;
{
printspec ps;
hypcurve(0.7);
ps.screendensity = 60.0;
ps.screenangle = 45.0;
ps.xpixperinch = -1.0;
ps.ypixperinch = -1.0;
ps.scaletrim = 1.0;
ps.bitsper = 8;
ps.linescreen = 0;
fprintf(outf,"\n translate scale\n");
fprintf(outf,"pop pop\n");
if(ps.linescreen)
fprintf(outf,"%f %f {pop} setscreen\n",ps.screendensity,ps.screenangle);
else
fprintf(outf,"%f %f {dup mul exch dup mul add 1 exch sub} setscreen\n",
ps.screendensity,ps.screenangle);
inimage = image;
tobwps(outf,bwgetimgrow,cortab,ps.bitsper,inimage->xsize,inimage->ysize);
}
frametorgbps(outf,image)
FILE *outf;
IMAGE *image;
{
printspec ps;
hypcurve(0.7);
ps.screendensity = 60.0;
ps.screenangle = 45.0;
ps.xpixperinch = -1.0;
ps.ypixperinch = -1.0;
ps.scaletrim = 1.0;
ps.bitsper = 8;
ps.linescreen = 0;
fprintf(outf,"\n translate scale\n");
fprintf(outf,"pop pop\n");
if(ps.linescreen)
fprintf(outf,"%f %f {pop} setscreen\n",ps.screendensity,ps.screenangle);
else
fprintf(outf,"%f %f {dup mul exch dup mul add 1 exch sub} setscreen\n",
ps.screendensity,ps.screenangle);
inimage = image;
torgbps(outf,rgbgetimgrow,cortab,ps.bitsper,inimage->xsize,inimage->ysize,1);
}
static hypcurve(p)
float p;
{
float b;
float x, y;
int i;
b = (1.0/p) - p;
for(i=0; i<256; i++) {
x = i/255.0;
y = 1.0-(1.0/((x*b)+p) - p)/b;
cortab[i] = (255*y)+0.5;
}
}
/*
* convert an image into B/W postscript
*
*
*/
static unsigned char *hi, *low;
tobwps(outf,getfunc,cortab,bitsper,xsize,ysize)
FILE *outf;
int (*getfunc)();
short cortab[256];
int bitsper, xsize, ysize;
{
int y, picstrlen;
unsigned short *buf;
picstrlen = xsize*bitsper;
picstrlen = (picstrlen+7)/8;
/* allocate the pixel buffer */
fprintf(outf,"/picstr %d string def\n",picstrlen);
fprintf(outf,"%d %d %d\n",xsize,ysize,bitsper);
fprintf(outf,"[%d 0 0 -%d 0 %d]\n",xsize,ysize,ysize);
if(binaryout) {
fprintf(outf,"{currentfile picstr readstring pop}\n");
fprintf(outf,"image\r");
} else {
fprintf(outf,"{currentfile picstr readhexstring pop}\n");
fprintf(outf,"image\n");
}
/* send out the picture */
buf = (unsigned short *)malloc(xsize*sizeof(short));
pos = 0;
for( y=0; y<ysize; y++ ) {
(getfunc)(buf,y);
applytable(buf,cortab,xsize);
putpsrow(outf,buf,picstrlen,bitsper);
}
free(buf);
fprintf(outf,"\n");
}
/*
* convert an image into rgb postscript
*
*
*/
torgbps(outf,getfunc,cortab,bitsper,xsize,ysize,nproc)
FILE *outf;
int (*getfunc)();
short cortab[256];
int bitsper, xsize, ysize, nproc;
{
int y, z, picstrlen;
unsigned short *rbuf, *gbuf, *bbuf, *rgbbuf;
picstrlen = xsize*bitsper;
picstrlen = (picstrlen+7)/8;
rbuf = (unsigned short *)malloc(xsize*sizeof(short));
gbuf = (unsigned short *)malloc(xsize*sizeof(short));
bbuf = (unsigned short *)malloc(xsize*sizeof(short));
rgbbuf = (unsigned short *)malloc(3*xsize*sizeof(short));
if(nproc == 1) {
/* allocate the pixel buffer */
fprintf(outf,"/istr %d string def\n",3*picstrlen);
fprintf(outf,"%d %d %d\n",xsize,ysize,bitsper);
fprintf(outf,"[%d 0 0 -%d 0 %d]\n",xsize,ysize,ysize);
if(binaryout) {
fprintf(outf,"{currentfile istr readstring pop}\n");
fprintf(outf,"false 3\n");
fprintf(outf,"colorimage\r");
} else {
fprintf(outf,"{currentfile istr readhexstring pop}\n");
fprintf(outf,"false 3\n");
fprintf(outf,"colorimage\n");
}
/* send out the picture */
pos = 0;
for( y=0; y<ysize; y++ ) {
(getfunc)(rbuf,y,0);
applytable(rbuf,cortab,xsize);
(getfunc)(gbuf,y,1);
applytable(gbuf,cortab,xsize);
(getfunc)(bbuf,y,2);
applytable(bbuf,cortab,xsize);
intervleave3(rbuf,gbuf,bbuf,rgbbuf,xsize);
putpsrow(outf,rgbbuf,3*picstrlen,bitsper);
}
} else {
/* allocate the pixel buffer */
fprintf(outf,"/rstr %d string def\n",picstrlen);
fprintf(outf,"/gstr %d string def\n",picstrlen);
fprintf(outf,"/bstr %d string def\n",picstrlen);
fprintf(outf,"%d %d %d\n",xsize,ysize,bitsper);
fprintf(outf,"[%d 0 0 -%d 0 %d]\n",xsize,ysize,ysize);
if(binaryout) {
fprintf(outf,"{currentfile rstr readstring pop}\n");
fprintf(outf,"{currentfile gstr readstring pop}\n");
fprintf(outf,"{currentfile bstr readstring pop}\n");
fprintf(outf,"true 3\n");
fprintf(outf,"colorimage\r");
} else {
fprintf(outf,"{currentfile rstr readhexstring pop}\n");
fprintf(outf,"{currentfile gstr readhexstring pop}\n");
fprintf(outf,"{currentfile bstr readhexstring pop}\n");
fprintf(outf,"true 3\n");
fprintf(outf,"colorimage\n");
}
/* send out the picture */
pos = 0;
for( y=0; y<ysize; y++ ) {
(getfunc)(rbuf,y,0);
applytable(rbuf,cortab,xsize);
(getfunc)(gbuf,y,1);
applytable(gbuf,cortab,xsize);
(getfunc)(bbuf,y,2);
applytable(bbuf,cortab,xsize);
putpsrow(outf,rbuf,picstrlen,bitsper);
putpsrow(outf,gbuf,picstrlen,bitsper);
putpsrow(outf,bbuf,picstrlen,bitsper);
}
}
free(rbuf);
free(gbuf);
free(bbuf);
free(rgbbuf);
fprintf(outf,"\n");
}
/*
* convert an image into cmyk postscript
*
*
*/
tocmykps(outf,getfunc,cortab,bitsper,xsize,ysize,nproc)
FILE *outf;
int (*getfunc)();
short cortab[256];
int bitsper, xsize, ysize, nproc;
{
int y, z, picstrlen;
unsigned short *rbuf, *gbuf, *bbuf;
unsigned short *cbuf, *mbuf, *ybuf, *kbuf;
unsigned short *cmykbuf;
picstrlen = xsize*bitsper;
picstrlen = (picstrlen+7)/8;
rbuf = (unsigned short *)malloc(xsize*sizeof(short));
gbuf = (unsigned short *)malloc(xsize*sizeof(short));
bbuf = (unsigned short *)malloc(xsize*sizeof(short));
cbuf = (unsigned short *)malloc(xsize*sizeof(short));
mbuf = (unsigned short *)malloc(xsize*sizeof(short));
ybuf = (unsigned short *)malloc(xsize*sizeof(short));
kbuf = (unsigned short *)malloc(xsize*sizeof(short));
cmykbuf = (unsigned short *)malloc(4*xsize*sizeof(short));
if(nproc == 1) {
/* allocate the pixel buffer */
fprintf(outf,"/istr %d string def\n",4*picstrlen);
fprintf(outf,"%d %d %d\n",xsize,ysize,bitsper);
fprintf(outf,"[%d 0 0 -%d 0 %d]\n",xsize,ysize,ysize);
if(binaryout) {
fprintf(outf,"{currentfile istr readstring pop}\n");
fprintf(outf,"false 4\n");
fprintf(outf,"colorimage\r");
} else {
fprintf(outf,"{currentfile istr readhexstring pop}\n");
fprintf(outf,"false 4\n");
fprintf(outf,"colorimage\n");
}
/* send out the picture */
pos = 0;
for( y=0; y<ysize; y++ ) {
(getfunc)(rbuf,y,0);
(getfunc)(gbuf,y,1);
(getfunc)(bbuf,y,2);
vrgb_to_cmyk(rbuf,gbuf,bbuf,cbuf,mbuf,ybuf,kbuf,cortab,xsize);
intervleave4(cbuf,mbuf,ybuf,kbuf,cmykbuf,xsize);
putpsrow(outf,cmykbuf,4*picstrlen,bitsper);
}
} else {
/* allocate the pixel buffer */
fprintf(outf,"/cstr %d string def\n",picstrlen);
fprintf(outf,"/mstr %d string def\n",picstrlen);
fprintf(outf,"/ystr %d string def\n",picstrlen);
fprintf(outf,"/kstr %d string def\n",picstrlen);
fprintf(outf,"%d %d %d\n",xsize,ysize,bitsper);
fprintf(outf,"[%d 0 0 -%d 0 %d]\n",xsize,ysize,ysize);
if(binaryout) {
fprintf(outf,"{currentfile cstr readstring pop}\n");
fprintf(outf,"{currentfile mstr readstring pop}\n");
fprintf(outf,"{currentfile ystr readstring pop}\n");
fprintf(outf,"{currentfile kstr readstring pop}\n");
fprintf(outf,"true 4\n");
fprintf(outf,"colorimage\r");
} else {
fprintf(outf,"{currentfile cstr readhexstring pop}\n");
fprintf(outf,"{currentfile mstr readhexstring pop}\n");
fprintf(outf,"{currentfile ystr readhexstring pop}\n");
fprintf(outf,"{currentfile kstr readhexstring pop}\n");
fprintf(outf,"true 4\n");
fprintf(outf,"colorimage\n");
}
/* send out the picture */
pos = 0;
for( y=0; y<ysize; y++ ) {
(getfunc)(rbuf,y,0);
(getfunc)(gbuf,y,1);
(getfunc)(bbuf,y,2);
vrgb_to_cmyk(rbuf,gbuf,bbuf,cbuf,mbuf,ybuf,kbuf,cortab,xsize);
putpsrow(outf,cbuf,picstrlen,bitsper);
putpsrow(outf,mbuf,picstrlen,bitsper);
putpsrow(outf,ybuf,picstrlen,bitsper);
putpsrow(outf,kbuf,picstrlen,bitsper);
}
}
free(rbuf);
free(gbuf);
free(bbuf);
free(cbuf);
free(mbuf);
free(ybuf);
free(kbuf);
free(cmykbuf);
fprintf(outf,"\n");
}
putpsrow(outf,buf,picstrlen,bitsper)
FILE *outf;
short *buf;
int picstrlen, bitsper;
{
if(!psfirsted) {
makepstables();
psfirsted++;
}
if(binaryout)
putpsbinrow(outf,buf,picstrlen,bitsper);
else
putpsascrow(outf,buf,picstrlen,bitsper);
}
static putpsascrow(outf,buf,picstrlen,bitsper)
FILE *outf;
short *buf;
int picstrlen, bitsper;
{
int x, n, i, val;
switch(bitsper) {
case 1:
x=0;
for(n=2*picstrlen; n--; ) {
val = 0;
for(i=0; i<4; i++) {
val <<= 1;
val |= (buf[x]&0x80) >> 7;
x++;
}
psputchar("0123456789abcdef"[val],outf);
}
break;
case 2:
x=0;
for(n=2*picstrlen; n--; ) {
val = 0;
for(i=0; i<2; i++) {
val <<= 2;
val |= (buf[x]&0xc0) >> 6;
x++;
}
psputchar("0123456789abcdef"[val],outf);
}
break;
case 4:
x=0;
for(n=2*picstrlen; n--; ) {
val = (buf[x]&0xf0) >> 4;
x++;
psputchar("0123456789abcdef"[val],outf);
}
break;
case 8:
x=0;
for(n=2*picstrlen; n--; ) {
val = buf[x];
if(val > 255)
fprintf(stderr,"psimg: bad poop\n");
x++;
n--;
psputchar(hi[val],outf);
psputchar(low[val],outf);
}
break;
default:
fprintf(stderr,"psimg: bits per pixel must be a power of 2!!\n");
exit(1);
}
}
static putpsbinrow(outf,buf,picstrlen,bitsper)
FILE *outf;
short *buf;
int picstrlen, bitsper;
{
int x, n, i, val;
switch(bitsper) {
case 1:
x=0;
for(n=picstrlen; n--; ) {
val = 0;
for(i=0; i<8; i++) {
val <<= 1;
val |= (buf[x]&0x80) >> 7;
x++;
}
fputc(val,outf);
}
break;
case 8:
x=0;
for(n=picstrlen; n--;) {
val = buf[x];
if(val > 255)
fprintf(stderr,"psimg: bad poop\n");
x++;
fputc(val,outf);
}
break;
default:
fprintf(stderr,"psimg: BLAT bits per pixel must be 1 or 8\n");
exit(1);
}
}
static makepstables()
{
int i;
hi = (unsigned char *)malloc(256);
low = (unsigned char *)malloc(256);
for(i=0; i<256; i++) {
hi[i] = "0123456789abcdef"[i>>4];
low[i] = "0123456789abcdef"[i&0xf];
}
}
static psputchar(c,outf)
int c;
FILE *(outf);
{
fputc(c,outf);
if(++pos == 70) {
fputc('\n',outf);
pos = 0;
}
}
psputinit()
{
pos = 0;
}
static intervleave3(rbuf,gbuf,bbuf,rgbbuf,n)
short *rbuf, *gbuf, *bbuf, *rgbbuf;
int n;
{
while(n--) {
*rgbbuf++ = *rbuf++;
*rgbbuf++ = *gbuf++;
*rgbbuf++ = *bbuf++;
}
}
static intervleave4(cbuf,mbuf,ybuf,kbuf,cmykbuf,n)
short *cbuf, *mbuf, *ybuf, *kbuf, *cmykbuf;
int n;
{
while(n--) {
*cmykbuf++ = *cbuf++;
*cmykbuf++ = *mbuf++;
*cmykbuf++ = *ybuf++;
*cmykbuf++ = *kbuf++;
}
}